//
//  NetworkTools.swift
//  测试-05-AFN-Swift
//
//  Created by 高伦展 on 2017/12/3.
//  Copyright © 2017年 glz. All rights reserved.
//

import UIKit
import Alamofire

//网络工具
class NetworkTools {

    private let appKey = "2722407356"
    private let appSecret = "ead14cc45c21f1dbd6791347a9377a1d"
    private let redirectUrl = "http://zhanxinstudio.info"
    
    typealias HMRequestCallBack = (_ result:AnyObject?,_ error: Error?) -> ()
    
    static let sharedTools = NetworkTools()

}

// MARK: - 发布微博
extension NetworkTools{
    /// 发布微博
    /// - see:[http://open.weibo.com/wiki/2/statuses/update](http://open.weibo.com/wiki/2/statuses/update)
    func sendStatus(status:String,image:UIImage?, finished:@escaping HMRequestCallBack){
        
        var params = [String:AnyObject]()
        
        params["status"] = status as AnyObject
        
        if image == nil{
        
        let urlString = "https://api.weibo.com/2/statuses/update.json"
        
        tokenRequest(method: HTTPMethod.post,
                URLString: urlString,
                parameters: params as [String : AnyObject],
                finished: finished)
        }else{
            let urlString = "https://upload.api.weibo.com/2/statuses/upload.json"
            let data = UIImagePNGRepresentation(image!)
            upload(URLString: urlString, data: data!, name: "pic", parameters: params, finished: finished)
        }
    }
}

// MARK: - 获取微博数据
extension NetworkTools{
    /// 加载微博数据
    /// - see:[http://open.weibo.com/wiki/2/statuses/home_timeline](http://open.weibo.com/wiki/2/statuses/home_timeline)
    func loadStatus(since_id:Int, max_id:Int, finished:@escaping HMRequestCallBack){
        
        var params = [String:AnyObject]()
        
        if since_id > 0 {
            params["since_id"] = since_id as AnyObject
        }else if max_id > 0{
            params["max_id"] = (max_id - 1) as AnyObject
        }
        
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        
        tokenRequest(method: HTTPMethod.get, URLString: urlString, parameters: params as [String : AnyObject], finished: finished)
    }
}

// MARK: - 用户相关方法
extension NetworkTools{
    
    /// 加载用户信息
    /// - see:[http://open.weibo.com/wiki/2/users/show](http://open.weibo.com/wiki/2/users/show)
    func loadUserInfo(uid:String, finished:@escaping HMRequestCallBack){
       
        var params = [String:AnyObject]()
        
        let urlString = "https://api.weibo.com/2/users/show.json"
        
        params["uid"] =  uid as AnyObject
        
        tokenRequest(method: HTTPMethod.get, URLString: urlString, parameters: params as [String : AnyObject], finished: finished)
    }
}

// MARK: - OAuth 相关方法
extension NetworkTools{
    ///OAuth 授权 URL
    /// - see:[http://open.weibo.com/wiki/Oauth2/authorize](http://open.weibo.com/wiki/Oauth2/authorize)
    var oauthURL : NSURL {
        
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(redirectUrl)"
        
        return NSURL(string: urlString)!
    }
    
    ///加载accesstoken
    /// - see:[http://open.weibo.com/wiki/Oauth2/access_token](http://open.weibo.com/wiki/Oauth2/access_token)
    func loadAccessToken(code:String,finished: @escaping HMRequestCallBack){
        let urlString = "https://api.weibo.com/oauth2/access_token"
        
        let params = ["client_id":appKey,
                      "client_secret":appSecret,
                      "grant_type":"authorization_code",
                      "code":code,
                      "redirect_uri":redirectUrl]
        
        request(method: HTTPMethod.post,
                URLString: urlString,
                parameters: params as [String : AnyObject],
                finished: finished)
        
    }
}

// MARK: - 封装 AFN 网络方法
extension NetworkTools{
    
    private func appendToken(parameters:inout [String:AnyObject]?) -> Bool{
        
        guard let token = UserAccountViewModel.sharedUserAccount.accessToken else{
            
            return false
        }
        
        if parameters == nil{
            parameters = [String:AnyObject]()
        }
        
        parameters!["access_token"] = token as AnyObject
        
        return true
    }
    
    ///使用token进行网络请求
    func tokenRequest(method:HTTPMethod,URLString:String, parameters:[String: AnyObject]?,finished: @escaping HMRequestCallBack) {
        
        //判断 token 是否有效
        var parameters = parameters
        if !appendToken(parameters: &parameters){
            finished(nil, NSError(domain: "cn.glz.error", code: -1001, userInfo: ["message":"token is null"]))
            
            return
        }
        
       
        request(method: method, URLString: URLString, parameters: parameters, finished: finished)
    }
    
    ///网络请求
    func request(method:HTTPMethod,URLString:String,parameters:[String: AnyObject]?,finished: @escaping HMRequestCallBack) {
        
        Alamofire.request(URLString, method: method, parameters: parameters).responseJSON(completionHandler: { (response) in
            
            if response.result.isFailure{
                print("network request error \(response.result.error)")
            }
            
            finished(response.result.value as AnyObject,response.result.error)
        })
    }
    //上传图片
    private func upload(URLString:String,data:Data,name:String, parameters:[String: AnyObject]?,finished: @escaping HMRequestCallBack){
        
        //判断 token 是否有效
        var parameters = parameters
        if !appendToken(parameters: &parameters){
            finished(nil, NSError(domain: "cn.glz.error", code: -1001, userInfo: ["message":"token is null"]))
            
            return
        }
        
        /**
         1. data 要上传文件的二进制数据
         2. name 是服务器定义的字段名称 － 后台接口文档会提示
         3. fileName 是保存在服务器的文件名，但是：现在通常可以`乱写`，后台会做后续的处理
         - 根据上传的文件，生成 缩略图，中等图，高清图
         - 保存在不同路径，并且自动生成文件名
         
         - fileName 是 HTTP 协议定义的属性
         4. mimeType / contentType: 客户端告诉服务器，二进制数据的准确类型
         - 大类型/小类型
         * image/jpg image/gif image/png
         * text/plain text/html
         * application/json
         - 无需记忆
         - 如果不想告诉服务器准确的类型
         * application/octet-stream
         */
        
        Alamofire.upload(multipartFormData: { (formData) in
            formData.append(data, withName: name, fileName: "xxx", mimeType: "application/octet-stream")
            
            if let parameters = parameters{
                for (k,v) in parameters{
                    let str = v as! String
                    let strData = str.data(using: String.Encoding.utf8)!
                    
                    formData.append(strData, withName: k)
                }
            }
            
        }, to: URLString) { (encodingResult) in
            switch encodingResult{
                case .success(request: let alaupload, streamingFromDisk: _, streamFileURL: _):
                    alaupload.responseJSON(completionHandler: { (response) in
                        
                        if response.result.isFailure{
                            print("network request error \(response.result.error)")
                        }
                        
                        finished(response.result.value as AnyObject,response.result.error)
                    })
                case .failure(let error):
                    print("error: \(error)")
                }
        }
        
//        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
//              formData.appendPart(withFileData: data, name: name, fileName: "glz", mimeType: "application/octet-stream")
//        }, progress: { (progress) in
//            
//        }, success: { (task, result) in
//            finished(result as AnyObject, nil)
//        }) { (task, error) in
//            finished(nil, error)
//        }
    }
}


